package link.jfire.jnet.client;

import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.Future;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class FutureClient extends AioClient
{
    private Queue<ResponseFuture> futures = new ConcurrentLinkedQueue<>();
    private Lock                  lock    = new ReentrantLock();
                                          
    public Future<?> buildFuture()
    {
        ResponseFuture future = new ResponseFuture(lock, lock.newCondition());
        futures.add(future);
        return future;
    }
    
    @Override
    public void popOneFuture(Object obj)
    {
        ResponseFuture future = futures.poll();
        future.result = obj;
        lock.lock();
        try
        {
            future.hasResponse.signal();
        }
        finally
        {
            lock.unlock();
        }
    }
    
    @Override
    public void releaseAllFuture(Throwable e)
    {
        lock.lock();
        ResponseFuture future;
        try
        {
            do
            {
                future = futures.poll();
                if (future != null)
                {
                    future.e = e;
                    future.hasResponse.signal();
                }
            } while (true);
        }
        finally
        {
            lock.unlock();
        }
    }
}
